package com.cloudwave.trailends.ui;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BaiduMap.OnMapTouchListener;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationConfiguration.LocationMode;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.PolylineOptions;
import com.baidu.mapapi.model.LatLng;
import com.cloudwave.trailends.AppContext;
import com.cloudwave.trailends.Constants;
import com.cloudwave.trailends.R;
import com.cloudwave.trailends.compo.BaseActivity;
import com.cloudwave.trailends.domain.LinePoint;
import com.cloudwave.trailends.service.RidingService;
import com.cloudwave.trailends.utils.CollectionUtils;
import com.cloudwave.trailends.utils.DateUtils;
import com.lidroid.xutils.DbUtils;
import com.lidroid.xutils.db.sqlite.Selector;
import com.lidroid.xutils.exception.DbException;

/**
 * 
 * @author DolphinBoy 地图界面
 * @email 569141948@qq.com
 * @date 2014-4-27
 * @time 下午3:24:41
 * 
 */

public class MapViewActivity extends BaseActivity {
	private final static String TAG = "MapViewActivity";

	private ImageButton btnBack;
//  	private ImageButton btnOK;
  	private TextView tvTitle;
  	
  	private TextView tvTotalMileage;
  	private TextView tvTotalPoint;
  	private TextView tvTotalTime;
  	
  	private ImageButton ibLocate;
  	
	// 地图相关
	private MapView mapView;
	private static BaiduMap baiduMap;
	 //*_* 定位相关
    private LocationClient locClient;
  	private MyLocationListenner myListener;
//  	private boolean isFirstLoc = true;// 是否首次定位
  	
//  	private static LatLng lastLatLng;
  	
	private RidingReceiver ridingReceiver;
	
	private DbUtils dbu = null;
//	private static List<LinePoint> lList = null;
	private static Long lastPointTime = null;
	private static List<LatLng> points = null;
	private static LatLng startPoint = null;
	private static PolylineOptions options = null;
	
	private DecimalFormat df = new DecimalFormat("#0.00");
	private static LocationMode locationMode = LocationMode.COMPASS;  //对于默认值，应该参考用户意见
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//在使用SDK各组件之前初始化context信息，传入ApplicationContext
        //注意该方法要再setContentView方法之前实现
//        SDKInitializer.initialize(getApplicationContext());
		setContentView(R.layout.map_view);
		
		initView();
		initDb();
		initMap();
		
		String action = getIntent().getStringExtra("action");
		if ( "view".equalsIgnoreCase(action) ) {  //离线地图预览
			viewMap();
		} else {
			if ( RidingService.now_rlId == 0 ) {  //如果当前用户不是在骑行中，则打开地图页面就开始定位
				initLocator();
	        }
			locate();
        	loadPath();
		}
	}
	
	@Override
	protected void onStart() {
		super.onStart();
		registerReceiver();
		
		if ( RidingService.now_rlId == 0 ) {  //如果当前用户不是在骑行中，则打开地图页面就开始定位
			initLocator();
        }
		locate();
	}

	private void initView() {
		btnBack = (ImageButton) findViewById(R.id.btnBack);
		tvTitle = (TextView) findViewById(R.id.tvTitle);
//		btnOK = (ImageButton) findViewById(R.id.btnOK);
		tvTotalMileage = (TextView) findViewById(R.id.totalMileage);
		tvTotalTime = (TextView) findViewById(R.id.totalTime);
		tvTotalPoint = (TextView) findViewById(R.id.totalPoint);
		
		ibLocate = (ImageButton) findViewById(R.id.ibLocate);
		
		tvTitle.setText("我的位置");
		
		String tMStr = getResources().getString(R.string.detail_mileage_holder);  
        String tMNewStr = String.format(tMStr, "0.00"); 
		tvTotalMileage.setText(tMNewStr);
		
		String tStr = getResources().getString(R.string.stat_times_en);  
        String tNewStr = String.format(tStr, 0, 0, 0);  
		tvTotalTime.setText(tNewStr);
		
		btnBack.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				MapViewActivity.this.finish();
			}
		});
		
		ibLocate.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				initLocator();
				locate();
			}
		});
	}
	
	private void initDb() {
		if ( dbu == null ) {
			dbu = DbUtils.create(this.getApplicationContext(), Constants.DB_NAME);
		}
	}
	
	// 初始化地图
	private void initMap() {
		mapView = (MapView) findViewById(R.id.mapView);
		baiduMap = mapView.getMap();
		//普通地图
		baiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
		baiduMap.setMyLocationEnabled(true);
		baiduMap.setMyLocationConfigeration(new MyLocationConfiguration(locationMode, true, null));
		
		mapView.removeViewAt(1);  //移除百度左下角LOGO
//		mapView.removeViewAt(2);  //移除默认的地图缩放控件
		
		baiduMap.getUiSettings().setCompassEnabled(false);  //禁止左上角的指南针
		
		baiduMap.setOnMapTouchListener(new OnMapTouchListener() {

			@Override
			public void onTouch(MotionEvent arg0) {
				locationMode = LocationMode.NORMAL;
//				ibLocate.setImageResource(R.drawable.main_icon_location);
//				ibLocate.setText(R.string.loc_normal);
				ibLocate.setImageResource(R.drawable.main_icon_location);
				baiduMap.setMyLocationConfigeration(new MyLocationConfiguration(locationMode, true, null));
				locClient.requestLocation();
			}
			
		});
		
		//调整百度地图图标的位置
//		ImageView iv = (ImageView) mapView.getChildAt(1);
//      iv.setPadding(0, 0, 0, 100);
        
//        View view = mapView.getChildAt(2);
//        view.setVisibility(View.INVISIBLE);
		//调整缩放控件的位置
//		ZoomControls zoomControls = (ZoomControls) mapView.getChildAt(2);
//      zoomControls.setPadding(0, 0, 0, 100);
		
//		List<LatLng> points = new ArrayList<LatLng>();
//		LatLng ll1 = new LatLng(22.963175, 116.400244);
//		LatLng ll2 = new LatLng(22.963175, 116.420244);
//		
//		points.add(ll1);
//		points.add(ll2);
//		PolylineOptions options = new PolylineOptions();
//		options.color(0xFF0070D0).width(10).points(points);
//		baiduMap.addOverlay(options);
//		
//		MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll1);
//		baiduMap.setMapStatus(u);
//		baiduMap.animateMapStatus(u);  //用这个方法就会黑屏
	}
	
	private void initLocator() {
		if (locClient != null && locClient.isStarted()) {
    		return ;
    	}
        locClient = ((AppContext) getApplication()).getLocationClient();
        myListener = new MyLocationListenner();
        locClient.registerLocationListener(myListener);
        AppContext.getLocClientOption().setLocationMode(com.baidu.location.LocationClientOption.LocationMode.Hight_Accuracy);
        locClient.setLocOption(AppContext.getLocClientOption());
	}

	private void locate() {
		ibLocate.setBackgroundResource(R.drawable.map_loc_progress);
		
		switch ( locationMode ) {
		case NORMAL:
			locationMode = LocationMode.FOLLOWING;
			ibLocate.setImageResource(R.drawable.main_icon_follow);
//			ibLocate.setText(R.string.loc_follow);
			break;
		case COMPASS:
			locationMode = LocationMode.NORMAL;
			ibLocate.setImageResource(R.drawable.main_icon_location);
//			ibLocate.setText(R.string.loc_normal);
			break;
		case FOLLOWING:
			locationMode = LocationMode.COMPASS;
			ibLocate.setImageResource(R.drawable.main_icon_compass);
//			ibLocate.setText(R.string.loc_compass);
			break;
		default:
			break;
		}
		
		baiduMap.setMyLocationConfigeration(new MyLocationConfiguration(locationMode, true, null));
		
		
		if (locClient != null) {
	        locClient.start();
		} else {
			initLocator();
		}
		if ( locClient.isStarted() ) {
			// 定位请求
//			int reqType = locClient.requestLocation();
			locClient.requestLocation();
		}
	}
	
	//查看离线地图调用此方法
	private void viewMap() {
		double longitude = getIntent().getDoubleExtra("x", 0);
		double latitude = getIntent().getDoubleExtra("y", 0);
		
		MapStatusUpdate u1 = MapStatusUpdateFactory.zoomTo(14.0f);
		baiduMap.setMapStatus(u1);
		
		LatLng ll = new LatLng(latitude, longitude);
		MapStatusUpdate u2 = MapStatusUpdateFactory.newLatLng(ll);
		baiduMap.animateMapStatus(u2);
	}
	
	//考虑重构 和PathView中有重复代码
	private static Handler handler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			if ( msg.what == 1 ) {
//				List<LatLng> points = new ArrayList<LatLng>();
//				List<LatLng> points = new ArrayList<LatLng>();
//				LatLng startPoint = null;
//				LatLng endPoint = null;
//				int sz = lList.size();
//				for (int i=0; i<sz; i++) {
//					LinePoint l = lList.get(i);
//					LatLng ll = new LatLng(l.getLatitude(), l.getLongitude());
//					if (i == 0) {
//						startPoint = new LatLng(l.getLatitude(), l.getLongitude());
//					}
////					if (i == (sz-1)) {
////						endPoint = new LatLng(l.getLatitude(), l.getLongitude());
////					}
//					points.add(ll);
//				}
				
//				lastLatLng = endPoint;
				
				//这里要根据lList.size() 来计算并设置zoom setZoom  ###
				
				//设置线段的颜色，需要传入32位的ARGB格式。默认为黑色( 0xff000000)。
				//http://www.cnblogs.com/Dahaka/archive/2012/03/03/2374799.html
				PolylineOptions options = new PolylineOptions().color(0xFF0070D0).width(10)
						.points(points).zIndex(1);
				baiduMap.addOverlay(options);
				
				BitmapDescriptor startBitmap = BitmapDescriptorFactory  
					    .fromResource(R.drawable.riding_to_start);
				OverlayOptions startOption = new MarkerOptions().position(startPoint)
						.icon(startBitmap).zIndex(2);
				baiduMap.addOverlay(startOption);
				
//				BitmapDescriptor endBitmap = BitmapDescriptorFactory  
//					    .fromResource(R.drawable.riding_to_end);
//				OverlayOptions endOption = new MarkerOptions().position(endPoint)
//						.icon(endBitmap).zIndex(2); 
//				baiduMap.addOverlay(endOption);
				
				if ( locationMode != LocationMode.NORMAL ) {
					//这里考虑根据路线距离来设定地图等级###
					MapStatusUpdate u1 = MapStatusUpdateFactory.zoomTo(14.0f);
//						baiduMap.animateMapStatus(u1);
					baiduMap.setMapStatus(u1);
					
					MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(startPoint);
//						baiduMap.animateMapStatus(u);
					baiduMap.setMapStatus(u);
	            }
			} else if ( msg.what == 2 ) {
//				List<LinePoint> lListNew = (List<LinePoint>) msg.obj;
//				List<LatLng> pointsNew = (List<LatLng>) msg.obj;
//				int sz = lListNew.size();
//				for (int i=0; i<sz; i++) {
//					LinePoint l = lList.get(i);
//					LatLng ll = new LatLng(l.getLatitude(), l.getLongitude());
//					points.add(ll);
//				}
				
//				points.addAll(pointsNew);
				//设置线段的颜色，需要传入32位的ARGB格式。默认为黑色( 0xff000000)。
				//http://www.cnblogs.com/Dahaka/archive/2012/03/03/2374799.html
//				PolylineOptions options = new PolylineOptions().color(0xFF0070D0).width(10)
//						.points(points).zIndex(1);
				
				options.points(points);
				
//				baiduMap.addOverlay(options);
				
//				BitmapDescriptor endBitmap = BitmapDescriptorFactory  
//					    .fromResource(R.drawable.riding_to_end);
//				OverlayOptions endOption = new MarkerOptions().position(endPoint)
//						.icon(endBitmap).zIndex(2); 
//				baiduMap.addOverlay(endOption);
				
				if ( locationMode != LocationMode.NORMAL ) {
					//这里考虑根据路线距离来设定地图等级###
					MapStatusUpdate u1 = MapStatusUpdateFactory.zoomTo(14.0f);
//						baiduMap.animateMapStatus(u1);
					baiduMap.setMapStatus(u1);
					
					MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(startPoint);
//						baiduMap.animateMapStatus(u);
					baiduMap.setMapStatus(u);
	            }
			}
			
			
		}
	};
		
	private void loadPath() {
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				Message msg = handler.obtainMessage();
				if ( CollectionUtils.isEmpty(points) ) {
					List<LinePoint> lList = null;
					try {
//						 DbUtils dbu = DbUtils.create(MapViewActivity.this, Constants.DB_NAME);
						lList = dbu.findAll(Selector.from(LinePoint.class).where("ridingline_id", "==", RidingService.now_rlId).orderBy("createtime_"));
					} catch (DbException e) {
						Toast.makeText(MapViewActivity.this, "数据加载失败~_~", Toast.LENGTH_SHORT).show();
						Log.e(TAG, "查询记录数据异常:", e);
						return ;
					}
					if ( CollectionUtils.isNotEmpty(lList) ) {
						points = new ArrayList<LatLng>();
						
						int sz = lList.size();
						for (int i=0; i<sz; i++) {
							LinePoint l = lList.get(i);
							LatLng ll = new LatLng(l.getLatitude(), l.getLongitude());
							if (i == 0) {
								startPoint = new LatLng(l.getLatitude(), l.getLongitude());
							}
							if (i == (sz-1)) {
//								endPoint = new LatLng(l.getLatitude(), l.getLongitude());
								lastPointTime = l.getTimestamp();
							}
							points.add(ll);
						}
						
						msg.what = 1;
						handler.sendMessage(msg);
					}
					
				} else {
					List<LinePoint> lListNew = null;
					try {
//						 DbUtils dbu = DbUtils.create(MapViewActivity.this, Constants.DB_NAME);
						lListNew = dbu.findAll(Selector.from(LinePoint.class)
								.where("ridingline_id", "==", RidingService.now_rlId)
								.where("timestamp_", ">", lastPointTime).orderBy("createtime_"));
					} catch (DbException e) {
						Toast.makeText(MapViewActivity.this, "数据加载失败~_~", Toast.LENGTH_SHORT).show();
						Log.e(TAG, "查询记录数据异常:", e);
						return ;
					}
					
					if ( CollectionUtils.isNotEmpty(lListNew) ) {
						
						int sz = lListNew.size();
						for (int i=0; i<sz; i++) {
							LinePoint l = lListNew.get(i);
							LatLng ll = new LatLng(l.getLatitude(), l.getLongitude());
							points.add(ll);
						}
						
						msg.what = 2;
						handler.sendMessage(msg);
					}
				}
			}
		}).start();
	}
	
//	private void addedPath(BDLocation location) {
//		if ( lastLatLng == null ) {
//			return ;
//		}
//		
//		List<LatLng> points = new ArrayList<LatLng>();
//		LatLng newPoint = new LatLng(location.getLatitude(), location.getLongitude());
//		points.add(lastLatLng);
//		points.add(newPoint);
//		PolylineOptions options = new PolylineOptions().color(0xFF0070D0).width(10)
//				.points(points).zIndex(1);
//		baiduMap.addOverlay(options);
//		lastLatLng = newPoint;
//	}
	
	public class MyLocationListenner implements BDLocationListener {
    	
        @Override
        public void onReceiveLocation(BDLocation location) {
//        	ibLocate.setBackgroundResource(R.drawable.main_icon_location);  //这地方有问题, 应该去掉背景###
        	ibLocate.setBackgroundResource(R.color.lucency);  //这地方有问题, 应该去掉背景###
        	int result = location.getLocType();
            Log.i(TAG, "结果:"+result);
            
            //这里根据不同情况进行通知###
//          getLocType获取error code：
//          61 ： GPS定位结果
//          62 ： 扫描整合定位依据失败。此时定位结果无效。
//          63 ： 网络异常，没有成功向服务器发起请求。此时定位结果无效。
//          65 ： 定位缓存的结果。
//          66 ： 离线定位结果。通过requestOfflineLocaiton调用时对应的返回结果
//          67 ： 离线定位失败。通过requestOfflineLocaiton调用时对应的返回结果
//          68 ： 网络连接失败时，查找本地离线定位时对应的返回结果
//          161： 表示网络定位结果
//          162~167： 服务端定位失败
//          502：key参数错误
//          505：key不存在或者非法
//          601：key服务被开发者自己禁用
//          602：key mcode不匹配
//          501～700：key验证失败
            
            if (162 <= result && result <= 167) {
            	Toast.makeText(MapViewActivity.this, "定位失败啦~_~", Toast.LENGTH_SHORT).show();
            	Log.e(TAG, "服务端定位失败~_~");
            	return ;
            }
            
            if ( locationMode == LocationMode.NORMAL ) {
            	return ;
            }
            // 构造定位数据
            MyLocationData locData = new MyLocationData.Builder()
                .accuracy(location.getRadius())
                .direction(location.getDirection())  //此处设置开发者获取到的方向信息，顺时针0-360
                .latitude(location.getLatitude())
                .longitude(location.getLongitude()).build();
            // 设置定位数据
            baiduMap.setMyLocationData(locData);
            
//            if ( isFirstLoc ) {
//				isFirstLoc = false;
				
				MapStatusUpdate u1 = MapStatusUpdateFactory.zoomTo(16.0f);
//				baiduMap.animateMapStatus(u1);
				baiduMap.setMapStatus(u1);
				
				LatLng ll = new LatLng(location.getLatitude(),
						location.getLongitude());
				MapStatusUpdate u2 = MapStatusUpdateFactory.newLatLng(ll);
				baiduMap.animateMapStatus(u2);
//			}
				
			//如果不是在骑行中应该隔多久定位一次，如果是在骑行中就5秒一次
//            if ( locClient != null && locClient.isStarted() ) {
//            	locClient.stop();
//            }
        }
        
        public void onReceivePoi(BDLocation poiLocation) {
            if (poiLocation == null){
                return ;
            }
        }
    }
	public class RidingReceiver extends BroadcastReceiver {

		@Override
		public void onReceive(Context context, Intent intent) {
			Log.i(TAG, "---收到通知---");
			String action = intent.getAction();
			if (action.equals(RidingService.UPDATE_VALID_LOCATION)) {
				
				//如果locClient是单例这里就会有问题###
//				if (locClient != null && locClient.isStarted()) {
//					locClient.stop();
//				}
				
//				double latitude = intent.getDoubleExtra("latitude", 0d);
//				double longitude = intent.getDoubleExtra("longitude", 0d);
				
//				MyLocationData locData = new MyLocationData.Builder().accuracy(radius)
//                // 此处设置开发者获取到的方向信息，顺时针0-360
//                .direction(direction).latitude(latitude)
//                .longitude(longitude).build();
//				// 设置定位数据
//				baiduMap.setMyLocationData(locData);
//				
////				if ( isFirstLoc ) {
////					isFirstLoc = false;
//					
//					MapStatusUpdate u1 = MapStatusUpdateFactory.zoomTo(16.0f);
////					baiduMap.animateMapStatus(u1);
//					baiduMap.setMapStatus(u1);
//					
//					LatLng ll = new LatLng(latitude, longitude);
//					MapStatusUpdate u2 = MapStatusUpdateFactory.newLatLng(ll);
//					baiduMap.animateMapStatus(u2);
////				}
//				BDLocation location = new BDLocation();
//				location.setLatitude(latitude);
//				location.setLongitude(longitude);
				
				//这里应该判断距离超过50或者100m才更新
//				loadPath();
				
			} else if (action.equals(RidingService.UPDATE_STAT)) {
				
				float totalMileage = intent.getFloatExtra("totalMileage", 0.00f);
				int totalPoint = intent.getIntExtra("totalPoint", 0);
				long totalTime = intent.getLongExtra("totalTime", 0l);
				
				String tMStr = getResources().getString(R.string.detail_mileage_holder);  
		        String tMNewStr = String.format(tMStr, df.format(totalMileage / 1000)); 
		        tvTotalMileage.setText(tMNewStr);
				
				String tStr = getResources().getString(R.string.stat_times_en);
				int[] time = DateUtils.duration(totalTime * 1000);
		        String tNewStr = String.format(tStr, time[1], time[2], time[3]);
				tvTotalTime.setText(tNewStr);
				
				tvTotalPoint.setText(String.valueOf(totalPoint));
			}
		}
	}
	
	private void registerReceiver() {
		ridingReceiver = new RidingReceiver();
		IntentFilter filter = new IntentFilter();
		filter.addAction(RidingService.UPDATE_STAT);
		filter.addAction(RidingService.UPDATE_LOCATION);
		registerReceiver(ridingReceiver, filter);
	}
	
	@Override
	protected void onResume() {
		mapView.onResume();
		super.onResume();
	}
	
	@Override
	protected void onPause() {
		mapView.onPause();
		super.onPause();
	}

	@Override
	protected void onStop() {
		if ( locClient != null && locClient.isStarted() ) {
			locClient.stop();
		}
		
		if (ridingReceiver != null) {
			this.unregisterReceiver(ridingReceiver);
		}
		super.onStop();
		
	}

	@Override
	protected void onDestroy() {
		if (locClient != null) {
			if ( locClient.isStarted() ) {
				locClient.stop();
			}
			if (RidingService.now_rlId == 0) {  //如果当前用户不是在骑行中，就可以关闭定位服务
				locClient = null;
			}
		}
		
		baiduMap.setMyLocationEnabled(false);
		mapView.onDestroy();
		mapView = null;
		super.onDestroy();
	}

}
